package com.evil.application.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.evil.application.pojo.dto.ApplicationInfoReqDTO;
import com.evil.application.pojo.dto.ApplicationReqDTO;
import com.evil.application.pojo.entity.ApplicationInfo;
import com.evil.common.application.util.ApplicationRedisKeyUtil;
import com.evil.common.core.constant.RedisConstant;
import com.evil.common.core.enums.RCodeEnum;
import com.evil.common.core.exception.BusinessException;
import com.evil.common.core.util.CacheMapperUtil;
import com.evil.common.core.util.StreamUtil;
import org.apache.ibatis.annotations.Param;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 应用表
 *
 * @author liyang
 * @date 2023-02-15 16:01
 */
public interface ApplicationInfoMapper extends BaseMapper<ApplicationInfo> {

    Optional<ApplicationInfo> isExistById(Long id);

    default Optional<ApplicationInfo> isExistById_Cache(Long id) {
        return CacheMapperUtil.cacheById(
                id,
                ApplicationInfo.class,
                this::findById,
                ApplicationRedisKeyUtil::requestUuidPackageKey,
                RedisConstant.REQUEST_UUID_EXPIRE_IN_SECOND
        );
    }

    default ApplicationInfo findById(Long id) {
        return this.isExistById(id).orElseThrow(() -> new BusinessException(RCodeEnum.APPLICATION_INFO_NOT_EXIST));
    }

    default ApplicationInfo findById_Cache(Long id) {
        return this.isExistById_Cache(id).orElseThrow(() -> new BusinessException(RCodeEnum.APPLICATION_INFO_NOT_EXIST));
    }

    Optional<ApplicationInfo> isExistByKey(String key);

    default Optional<ApplicationInfo> isExistByKey_Cache(String key) {
        return CacheMapperUtil.cacheById(
                key,
                ApplicationInfo.class,
                this::findByKey,
                ApplicationRedisKeyUtil::requestUuidAppKeyKey,
                RedisConstant.REQUEST_UUID_EXPIRE_IN_SECOND
        );
    }

    default ApplicationInfo findByKey(String key) {
        return this.isExistByKey(key).orElseThrow(() -> new BusinessException(RCodeEnum.APPLICATION_INFO_NOT_EXIST));
    }

    default ApplicationInfo findByKey_Cache(String key) {
        return this.isExistByKey_Cache(key).orElseThrow(() -> new BusinessException(RCodeEnum.APPLICATION_INFO_NOT_EXIST));
    }

    List<ApplicationInfo> findByIds(@Param("ids") Collection<Long> ids, @Param("filterDeleted") boolean filterDeleted);

    default List<ApplicationInfo> findByIds_Cache(Collection<Long> ids, boolean filterDeleted) {
        return CacheMapperUtil.cacheByIds(
                ids,
                filterDeleted,
                ApplicationInfo.class,
                this::findByIds,
                ApplicationInfo::getApplicationId,
                ApplicationInfo::getIsDeleted,
                null,
                ApplicationRedisKeyUtil::requestUuidPackageKeyMap,
                RedisConstant.REQUEST_UUID_EXPIRE_IN_SECOND
        );
    }

    List<ApplicationInfo> findByKeys(@Param("keys") Collection<String> keys, @Param("filterDeleted") boolean filterDeleted);

    default List<ApplicationInfo> findByKeys_Cache(Collection<String> keys, boolean filterDeleted) {
        return CacheMapperUtil.cacheByIds(
                keys,
                filterDeleted,
                ApplicationInfo.class,
                this::findByKeys,
                ApplicationInfo::getApplicationKey,
                ApplicationInfo::getIsDeleted,
                null,
                ApplicationRedisKeyUtil::requestUuidAppKeyKeyMap,
                RedisConstant.REQUEST_UUID_EXPIRE_IN_SECOND
        );
    }

    List<ApplicationInfo> findByEnterpriseId(Long enterpriseId);

    default Map<Long, ApplicationInfo> findMapByIds(Collection<Long> ids, boolean filterDeleted) {
        return StreamUtil.toMapK(this.findByIds(ids, filterDeleted), ApplicationInfo::getApplicationId);
    }

    default Map<String, ApplicationInfo> findMapByKeys(Collection<String> keys, boolean filterDeleted) {
        return StreamUtil.toMapK(this.findByKeys(keys, filterDeleted), ApplicationInfo::getApplicationKey);
    }

    List<ApplicationInfo> findByApplicationReqDTO(ApplicationReqDTO applicationReqDTO);

    List<ApplicationInfo> findByApplicationInfoReqDTO(ApplicationInfoReqDTO applicationInfoReqDTO);
}